/******************************************************************************
**                                                                           **
**                 Proprietary and Confidential Information                  **
**                                                                           **
**                 Copyright (c) Conexant Systems, Inc. Unpublished                  **
**                                                                           **
** This source code and the algorithms implemented therein constitute        **
** confidential information and may compromise trade secrets of Conexant Systems,    **
** Inc. or its associates, and any unauthorized use thereof is prohibited.   **
**                                                                           **
******************************************************************************/

#ifndef dc_container_api_h
#define dc_container_api_h


// DBGMON WIN32 note.
//
// This header file is used for dbgmon builds to provide prototypes for the
// data container API functions (to support dbgmon side dbgext which allows
// host dlls to make "calls" to data container API functions).  For dbgmon
// compile, we try to expose only bare minimum by dummying out the container
// and producer/consumer data structures, and eliminating unnecessary header
// files.
//
// To enable API functions to be callable within DBGMON user dlls, we need
// to include the appropriate dll export/import function qualifiers.  For
// firmware, no function qualifier is used.
//

#include "dc_type.h"
#include "dc_return_codes.h"
#include "dc_dmb_api.h"
#ifndef WIN32
#ifdef LINUX
# include "ospl.h"
#else
# include "tx_api.h"
#endif
# define FUN_QUALIFIER
#else
# define FUN_QUALIFIER CPP DBGMON_API
#endif



// The state of production to a container.
typedef UINT32 DC_PRODUCTION_STATE;

#define DC_PRODUCTION_PENDING    0  // - no production yet to container; no producer registered yet!!
#define DC_PRODUCTION_READY      1  // - at least, a producer registered !!
#define DC_PRODUCTION_ACTIVE     2  // - production active
#define DC_PRODUCTION_COMPLETE   3  // - production to container complete; all producers unregistered!!
#define DC_PRODUCTION_COMPLETE_MONITOR_PENDED   4  // - production to container complete but pended by monitor.

typedef UINT32 DC_CONSUMPTION_STATE;
#define DC_CONSUMPTION_PENDING    0  // - no consumption yet to container; no consumer registered yet!!
#define DC_CONSUMPTION_READY      1  // - at least a consumer registered
#define DC_CONSUMPTION_ACTIVE     2  // - consumption active
#define DC_CONSUMPTION_COMPLETE   3  // - consumption to container complete; all consumers unregistered

// DC_CONTAINER_ALERT
//
// The DC_CONTAINER_ALERT is a type defined for use with data containers.
// It is used to indicate the reason a callback function is being executed.
//
typedef UINT32 DC_CONTAINER_ALERT;

// Defines for the type DC_CONTAINER_ALERT
//
//#define DC_CONTAINER_ALERT_DMB_ALLOC_READY           (1<<0)
#define DC_CONTAINER_ALERT_THRESHOLD                 (1<<1)
#define DC_CONTAINER_ALERT_AUX_THRESHOLD             (1<<2)
#define DC_CONTAINER_ALERT_PRODUCTION_COMPLETE       (1<<3)
#define DC_CONTAINER_ALERT_HEIGHT_SPECIFIED          (1<<4)
#define DC_CONTAINER_ALERT_ATTRIBUTES_SPECIFIED      (1<<5)
#define DC_CONTAINER_ALERT_CONSUMPTION_COMPLETE      (1<<6)  


// DC_CONTAINER_ALERT_FCN
//
// The DC_CONTAINER_ALERT_FCN is the callback function definition for
// a data container.  This function is called by the data container when
// an event occurs.  This function should keep its processing very short,
// and should NOT issue any blocking calls.  It should be treated similar
// to an interrupt service routine.
//
typedef void (*DC_CONTAINER_ALERT_FCN)
( DC_CONTAINER_ALERT alert,
  void *agent, // pointer to DC_CONSUMER or DC_PRODUCER
  UINT32 alertUserParam );

//
//
typedef void (*DC_CONTAINER_OVERLAP_CB_FCN)
(void *container, void *overalpCallbackArg, void *reserv);

// DC_CONTAINER_PRODUCER_CONSUMER
//
// This data structure is used to define attributes and flow control state for
// container producers and consumers.  A container may have multiple producers
// and multiple consumers.
//
typedef struct DC_CONTAINER_PRODUCER_CONSUMER_STRUCT
{
#ifdef WIN32
  // dummy out this data structure for dbgmon builds
  int foo;
#else
  UINT32 signature;   // known 32-bit number to indicate inited/registered

  // container to which this producer/consumer belongs, and pointer to next
  struct DC_CONTAINER_STRUCT *container;
  struct DC_CONTAINER_PRODUCER_CONSUMER_STRUCT *next;

  // name
  char *name;

  // user specified alert function and callback argument
  DC_CONTAINER_ALERT_FCN alertFcn;
  UINT32 alertUserParam;

  // track alerts which are arm'd
  DC_CONTAINER_ALERT alertMask;
  UINT32 unitThreshold;
  UINT32 auxUnitThreshold;

  DC_CONTAINER_ALERT deferred_alert;

  // flow control elements
  UINT32 cumulativeUnits;
  UINT32 cumulativeAuxUnits;

  // dmb and offset associated with flow control'ed producer/consumer location
  // offset is byte offset from first byte in dmb
  DC_DMB dmbCurrent;
  UINT32 dmbCurrentOffset;

  // walk list of DMBs handed to user via segment_get() function
  DC_DMB dmbSegment;

  // for only get partial data once if avialble.
  UINT32 scratchFlag1;
  UINT32 scratchFlag2;
#endif
} DC_CONTAINER_PRODUCER_CONSUMER;

#define DC_CONTAINER_PRODUCER DC_CONTAINER_PRODUCER_CONSUMER
#define DC_CONTAINER_CONSUMER DC_CONTAINER_PRODUCER_CONSUMER

#define DC_DMBBUF_PRODUCER DC_CONTAINER_PRODUCER
#define DC_CIRCBUF_PRODUCER DC_CONTAINER_PRODUCER
#define DC_DMBBUF_CONSUMER DC_CONTAINER_CONSUMER
#define DC_CIRCBUF_CONSUMER DC_CONTAINER_CONSUMER


// Debug handle.
//
// When using debug features of the data container system we operate outside
// the normal data container "lifecycle".  As such, we are at greater risk of
// using stale container pointers.  Thus, for debug API functions, instead of
// using the usual container pointers, use a separate debug handle which can
// detect if container has been deleted/created underneath the debug app.
//

typedef UINT32 DC_CONTAINER_DEBUG_HANDLE;



// DC_CONTAINER_GROUP
// for private use only.
typedef struct DC_CONTAINER_GROUP_STRUCT
{
#ifdef WIN32
  int foo;
#else
#ifdef LINUX
  OSPL_SEMAPHORE accessControl;
#else
  TX_SEMAPHORE accessControl;
#endif  
  struct DC_CONTAINER_STRUCT *containerHeadPtr;
  UINT32 nContainerAdded;
  UINT32 nContainerDeleted;

  DC_DMB  dmbHead;
  DC_DMB  dmbTail;
  UINT32  offset;
#endif
} DC_CONTAINER_GROUP;

// DC_CONTAINER
//

// Container infrastructure currently defines two classes of base
// container.  These are circular buffer and dmb buffer.  From these
// base container classes, additional derived containers can be
// created, called types.  The container class and type define the
// attributes of the container.  Separate versions are provided for
// both class and type.
//

#define DC_CONTAINER_VERSION 0

#define DC_CONTAINER_CLASS_CIRCBUF 1
#define DC_CONTAINER_CLASS_CIRCBUF_TYPE_BASE    0
#define DC_CONTAINER_CLASS_CIRCBUF_TYPE_IMGBUF  1

#define DC_CONTAINER_CLASS_DMBBUF  2
#define DC_CONTAINER_CLASS_DMBBUF_TYPE_BASE     0
#define DC_CONTAINER_CLASS_DMBBUF_TYPE_DMBIMG   1


typedef struct DC_CONTAINER_STRUCT
{
#ifdef WIN32
  // dummy out this data structure for dbgmon builds
  int foo;
#else
  UINT32 version;        // base container version
  UINT32 container_class; // base container class
  UINT32 type;           // container type (within class)
  UINT32 type_version;   // container type version

  UINT32 signature;      // known 32bit number to indicate

  char *name;

  DC_PRODUCTION_STATE production_state;
  DC_CONSUMPTION_STATE consumption_state;

  // pointer to next container in linked list of containers
  struct DC_CONTAINER_STRUCT *next;

  // handle for this data container.
  // NULL indicates that the container is not valid.
  DC_CONTAINER_DEBUG_HANDLE handle;

  // list of producers and consumers
  DC_CONTAINER_PRODUCER *producerHeadPtr;
  DC_CONTAINER_CONSUMER *consumerHeadPtr;

  // advanced flow control element
  UINT32 protectedUnits;
  // pointer to a overlap_to container, if overlapped, limits current container's production activity.
  struct DC_CONTAINER_STRUCT *overlap_to;  // (overlap_to, current)
  // user specified callback function and callback argument
  DC_CONTAINER_OVERLAP_CB_FCN overlapCallbackFcn;
  void *overlapCallbackArg;

  // pointer to a overlap_by container, if connnected, is limitted by current container's activity.
  struct DC_CONTAINER_STRUCT *overlap_by;  // (current, overlap_by)

  // flow control elements from slowest producer
  UINT32 producerCumulativeUnits;
  UINT32 producerCumulativeAuxUnits;
  DC_DMB producerDMBCurrent;

  // flow control elements from slowest consumer
  UINT32 consumerCumulativeUnits;
  UINT32 consumerCumulativeAuxUnits;
  DC_DMB consumerDMBCurrent;

  // mutex  (or binary semaphore) to protect producer/consumer linked lists, DMB lists, etc.
#ifdef LINUX  
  OSPL_MUTEX accessControl;
#else
  TX_MUTEX accessControl;
#endif  

  // dmb list walking and allocation/free tracking
  DC_DMB dmbHead;
  DC_DMB dmbTail;
  UINT32 dmbsAllocated;
  UINT32 dmbsFreed;

  // misc dmb related stuff
  UINT32 dmbSizeInBytes;
  UINT32 dmbAllocId;

  // misc circbuf related stuff
  UINT32 unitSizeInBytes;
  UINT32 nUnits;
  UINT32 yStart;
  void *base;

  struct {
    UINT32 enable;

    // point to the group
    DC_CONTAINER_GROUP *parentPtr;
    // point to next container in the group
    struct DC_CONTAINER_STRUCT *next;

    DC_DMB old_dmb;

    DC_DMB new_dmb1;
    DC_DMB new_dmb2;
    // beginning position to move data and be 1K aligned.
    UINT32 offset1;
    UINT32 offset2;
    // the count of data to move, equal to be (producerCumulativeUnits % dmbSizeInBytes)
    UINT32 units;
    // 1K aligned
    UINT32 alignedUnits1;
    UINT32 alignedUnits2;

    // mutext  (or binary semaphore) for group field of the container
#ifdef LINUX    
    OSPL_SEMAPHORE accessControl;
#else
    TX_SEMAPHORE accessControl;
#endif    
  } group;

  // monitor related variables
  struct {

    // set to non-zero when monitor of the container is enabled
    UINT32 enable;

    // flow control elements
    UINT32 cumulativeUnits;
    UINT32 cumulativeAuxUnits;

    // dmb and offset associated with flow control'ed monitor location
    // offset is byte offset from first byte in dmb
    DC_DMB dmbCurrent;
    UINT32 dmbCurrentOffset;

    // walk list of DMBs handed to user via segment_get() function
    DC_DMB dmbSegment;

    UINT32 scratchFlag1;
    UINT32 scratchFlag2;
  } monitor;

#endif
} DC_CONTAINER;

#define DC_CIRCBUF DC_CONTAINER
#define DC_DMBBUF DC_CONTAINER


//
//
// Generic container API functions.
//
//

FUN_QUALIFIER DC_RETURN_CODE dc__container_delete
( DC_CONTAINER *container);

FUN_QUALIFIER DC_RETURN_CODE dc__container_producer_setup
( DC_CONTAINER_PRODUCER *producer,
  char *name,
  DC_CONTAINER_ALERT_FCN alertFcn,
  UINT32 alertUserParam );

FUN_QUALIFIER DC_RETURN_CODE dc__container_producer_register
( DC_CONTAINER *container,
  DC_CONTAINER_PRODUCER *producer);

FUN_QUALIFIER DC_RETURN_CODE dc__container_producer_unregister
( DC_CONTAINER_PRODUCER *producer );

FUN_QUALIFIER DC_RETURN_CODE dc__container_consumer_setup
( DC_CONTAINER_CONSUMER *consumer,
  char *name,
  DC_CONTAINER_ALERT_FCN alertFcn,
  UINT32 alertUserParam);

FUN_QUALIFIER DC_RETURN_CODE dc__container_consumer_register 
( DC_CONTAINER *container,
  DC_CONTAINER_CONSUMER *consumer );

FUN_QUALIFIER DC_RETURN_CODE dc__container_consumer_unregister
( DC_CONTAINER_CONSUMER *consumer);

FUN_QUALIFIER DC_RETURN_CODE dc__container_monitor_on
( DC_CONTAINER_DEBUG_HANDLE handle );

FUN_QUALIFIER DC_RETURN_CODE dc__container_monitor_off
( DC_CONTAINER_DEBUG_HANDLE handle );


FUN_QUALIFIER DC_RETURN_CODE dc__container_status_get
( DC_CONTAINER *container,
  UINT32 *production_state,
  UINT32 *consumption_state,
  UINT32 *production_units,
  UINT32 *consumption_units,
  UINT32 *production_auxUnits,
  UINT32 *consumption_auxUnits,
  UINT32 *reserved6,  // specify as NULL
  UINT32 *reserved7); // specify as NULL

//
//
// CIRCBUF container API
//
//

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_create
( DC_CIRCBUF *circbuf,
  char *name,
  void *base,
  UINT32 unitSizeInBytes,
  UINT32 nUnits,
  UINT32 yStart );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_overlap
( DC_CIRCBUF *cirbuf,
  DC_CIRCBUF *overlapped_cirbuf,
  DC_CONTAINER_OVERLAP_CB_FCN overlapCallbackFcn,
  void *overlapCallbackArg);

FUN_QUALIFIER DC_RETURN_CODE dc__circbuf_holdback_units_specify
( DC_CIRCBUF *circbuf,
  UINT32 nUnits);

FUN_QUALIFIER DC_RETURN_CODE dc__circbuf_holdback_units_release
( DC_CIRCBUF *circbuf,
  UINT32 nUnits);

FUN_QUALIFIER DC_RETURN_CODE dc__circbuf_holdback_units_get
( DC_CIRCBUF *circbuf,
  UINT32 *nUnits); 

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_info_get
( DC_CIRCBUF *circbuf,
  char **name,
  void **base,
  UINT32 *unitSizeInBytes,
  UINT32 *nUnits,
  UINT32 *yStart );

// DC_RETURN_CODE dc_circbuf_status_get
//( DC_CIRCBUF *circbuf,
//  UINT32 *production_state,
//  UINT32 *consumption_state,
//  UINT32 *production_units,
//  UINT32 *consumption_units,
//  UINT32 *reserved4,  // specify as NULL
//  UINT32 *reserved5,  // specify as NULL
//  UINT32 *reserved6,  // specify as NULL
//  UINT32 *reserved7); // specify as NULL
#define dc_circbuf_status_get dc__container_status_get

// DC_RETURN_CODE dc_circbuf_delete
//( DC_IMGBUG *circbuf);
#define dc_circbuf_delete dc__container_delete


// DC_RETURN_CODE dc_circbuf_producer_setup
//( DC_CIRCBUF_PRODUCER *producer,
//  char *name,
//  DC_CONTAINER_ALERT_FCN alertFcn,
//  UINT32 alertUserParam );
#define dc_circbuf_producer_setup dc__container_producer_setup

// DC_RETURN_CODE dc_circbuf_producer_register
//( DC_CIRCBUF *circbuf,
//  DC_CIRCBUF_PRODUCER *producer);
#define dc_circbuf_producer_register dc__container_producer_register

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_producer_alerts_set
( DC_CIRCBUF_PRODUCER *producer,
  UINT32 alertMask,
  UINT32 unitThreshold );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_producer_empty_get
( DC_CIRCBUF_PRODUCER *producer,
  UINT32 *emptyUnits );

FUN_QUALIFIER DC_RETURN_CODE dc__circbuf_producer_overlap_empty_get 
( DC_CIRCBUF_PRODUCER *producer,
  UINT32 *emptyUnits,
  UINT32 *overlapUnits);

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_producer_yValue_get
( DC_CIRCBUF_PRODUCER *producer,
  UINT32 *yValue );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_producer_produce
( DC_CIRCBUF_PRODUCER *producer,
  UINT32 units );

// DC_RETURN_CODE dc_circbuf_producer_unregister
//( DC_CIRCBUF_PRODUCER *producer );
#define dc_circbuf_producer_unregister dc__container_producer_unregister


// DC_RETURN_CODE dc_circbuf_consumer_setup
//( DC_CIRCBUF_CONSUMER *consumer,
//  char *name,
//  DC_CONTAINER_ALERT_FCN alertFcn,
//  UINT32 alertUserParam);
#define dc_circbuf_consumer_setup dc__container_consumer_setup

// DC_RETURN_CODE dc_circbuf_consumer_register
//( DC_CIRCBUF *circbuf,
//  DC_CIRCBUF_CONSUMER *consumer );
#define dc_circbuf_consumer_register dc__container_consumer_register

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_consumer_alerts_set
( DC_CIRCBUF_CONSUMER *consumer,
  UINT32 alertMask,
  UINT32 unitThreshold );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_consumer_valid_get
( DC_CIRCBUF_CONSUMER *consumer,
  UINT32 *validUnits );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_consumer_yValue_get
( DC_CIRCBUF_CONSUMER *consumer,
  UINT32 *yValue );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_consumer_consume
( DC_CIRCBUF_CONSUMER *consumer,
  UINT32 units );

// DC_RETURN_CODE dc_circbuf_consumer_unregister
//( DC_CIRCBUF_CONSUMER *consumer);
#define dc_circbuf_consumer_unregister dc__container_consumer_unregister


// DC_RETURN_CODE dc_circbuf_monitor_on
//( DC_CONTAINER_DEBUG_HANDLE handle );
#define dc_circbuf_monitor_on dc__container_monitor_on

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_monitor_available_get
( DC_CONTAINER_DEBUG_HANDLE handle,
  UINT32 *availableUnits );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_monitor_yValue_get
( DC_CONTAINER_DEBUG_HANDLE handle,
  UINT32 *yValue );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_monitor_monitor
( DC_CONTAINER_DEBUG_HANDLE handle,
  UINT32 units );

// DC_RETURN_CODE dc_circbuf_monitor_off
//( DC_CONTAINER_DEBUG_HANDLE handle );
#define dc_circbuf_monitor_off dc__container_monitor_off


//
//
// DMBBUF container API
//
//



FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_create
( DC_DMBBUF *dmbbuf,
  char *name );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_info_get
( DC_DMBBUF *dmbbuf,
  char **name );


FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_setup_dmbAllocControl_specify
( DC_DMBBUF *dmbbuf,
  UINT32 maxDMBs,
  UINT32 dmbAllocId
  /* TBD allocFilterFcn */ );

// DC_RETURN_CODE dc_dmbbuf_delete
//( DC_DMBBUF *container);
#define dc_dmbbuf_delete dc__container_delete


// DC_RETURN_CODE dc_dmbbuf_status_get
//( DC_DMBBUF *dmbbuf,
//  UINT32 *production_state,
//  UINT32 *consumption_state,
//  UINT32 *reserved2,  // specify as NULL
//  UINT32 *reserved3,  // specify as NULL
//  UINT32 *reserved4,  // specify as NULL
//  UINT32 *reserved5,  // specify as NULL
//  UINT32 *reserved6,  // specify as NULL
//  UINT32 *reserved7); // specify as NULL
#define dc_dmbbuf_status_get dc__container_status_get

// DC_RETURN_CODE dc_dmbbuf_producer_setup
//( DC_DMBBUF_PRODUCER *consumer,
//  char *name,
//  DC_CONTAINER_ALERT_FCN alertFcn,
//  UINT32 alertUserParam);
#define dc_dmbbuf_producer_setup dc__container_producer_setup

// DC_RETURN_CODE dc_dmbbuf_producer_register
//( DC_DMBBUF *dmbbuf,
//  DC_DMBBUF_PRODUCER *producer );
#define dc_dmbbuf_producer_register dc__container_producer_register

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_producer_alerts_set
( DC_DMBBUF_PRODUCER *producer,
  UINT32 alertMask,
  UINT32 byteThreshold );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_producer_allocate
( DC_DMBBUF_PRODUCER *producer,
  UINT32 desiredEmptyBytes );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_producer_empty_get
( DC_DMBBUF_PRODUCER *producer,
  UINT32 *emptyBytes );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_producer_segment_get
( DC_DMBBUF_PRODUCER *producer,
  void **dataPtr,
  UINT32 *nBytes );

FUN_QUALIFIER DC_RETURN_CODE dc__dmbbuf_producer_dmb_count_get 
( DC_DMBBUF_PRODUCER *producer,
  UINT32 *n_dmbs_in_alloc,
  UINT32 *n_dmbs_in_bytes);

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_producer_produce
( DC_DMBBUF_PRODUCER *producer,
  UINT32 bytes,
  UINT32 auxUnits );

// DC_RETURN_CODE dc_dmbbuf_producer_unregister
//( DC_DMBBUF_PRODUCER *producer );
#define dc_dmbbuf_producer_unregister dc__container_producer_unregister


// DC_RETURN_CODE dc_dmbbuf_consumer_setup
//( DC_DMBBUF_CONSUMER *consumer,
//  char *name,
//  DC_CONTAINER_ALERT_FCN alertFcn,
//  UINT32 alertUserParam);
#define dc_dmbbuf_consumer_setup dc__container_consumer_setup

// DC_RETURN_CODE dc_dmbbuf_consumer_register
//( DC_DMBBUF *dmbbuf,
//  DC_DMBBUF_CONSUMER *consumer );
#define dc_dmbbuf_consumer_register dc__container_consumer_register

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_consumer_alerts_set
( DC_DMBBUF_CONSUMER *consumer,
  UINT32 alertMask,
  UINT32 byteThreshold,
  UINT32 auxUnitThreshold );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_consumer_valid_get
( DC_DMBBUF_CONSUMER *consumer,
  UINT32 *validBytes,
  UINT32 *validAuxUnits );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_consumer_segment_get
( DC_DMBBUF_CONSUMER *consumer,
  void **dataPtr,
  UINT32 *nBytes );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_consumer_consume
( DC_DMBBUF_CONSUMER *consumer,
  UINT32 bytes,
  UINT32 auxUnits );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_group_add 
( DC_CONTAINER_GROUP *group,
  DC_DMBBUF *container);

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_group_create 
( DC_CONTAINER_GROUP *group);

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_group_delete
( DC_CONTAINER_GROUP *group);


// DC_RETURN_CODE dc_dmbbuf_consumer_unregister
//( DC_DMBBUF_CONSUMER *consumer );
#define dc_dmbbuf_consumer_unregister dc__container_consumer_unregister

// DC_RETURN_CODE dc_dmbbuf_monitor_on
//( DC_CONTAINER_DEBUG_HANDLE handle );
#define dc_dmbbuf_monitor_on dc__container_monitor_on

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_monitor_available_get
( DC_CONTAINER_DEBUG_HANDLE handle,
  UINT32 *availableBytes,
  UINT32 *availableAuxUnits );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_monitor_segment_get
( DC_CONTAINER_DEBUG_HANDLE handle,
  void **dataPtr,
  UINT32 *nBytes );

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_monitor_monitor
( DC_CONTAINER_DEBUG_HANDLE handle,
  UINT32 bytes,
  UINT32 auxUnits );

// DC_RETURN_CODE dc_dmbbuf_monitor_off
//( DC_CONTAINER_DEBUG_HANDLE handle );
#define dc_dmbbuf_monitor_off dc__container_monitor_off



//
//
// Data container dbgmon extension.
//
// The data container infrastructure includes a dgbmon extension hander
// function which allows DBGMON side applications to make calls to the data
// container APIs.  This handler function must be registered with firmware
// side dbgmon module in order for the extension to be useable.
//
//

// Enables use of data container API by DBGMON debug extension.
DC_RETURN_CODE dc_container_dbgmon_setup(void);



//
//
// Debug API functions.
//
//

FUN_QUALIFIER DC_RETURN_CODE dc_container_debug_next_get
( DC_CONTAINER_DEBUG_HANDLE handle,
  DC_CONTAINER_DEBUG_HANDLE *next,
  UINT32 *container_class,
  UINT32 *type,
  UINT32 *nCreated,
  UINT32 *nDeleted );

FUN_QUALIFIER DC_RETURN_CODE dc_container_debug_auto_monitor_clear
( void );

FUN_QUALIFIER DC_RETURN_CODE dc_container_debug_delete
( DC_CONTAINER_DEBUG_HANDLE handle);

// must be multiple of 4 bytes
#define DC_CONTAINER_MATCH_STRING_SIZE 32

FUN_QUALIFIER DC_RETURN_CODE dc_container_debug_auto_monitor_add
( char matchString[DC_CONTAINER_MATCH_STRING_SIZE] );

FUN_QUALIFIER DC_RETURN_CODE dc_circbuf_debug_info_get
( DC_CONTAINER_DEBUG_HANDLE handle,
  char **name,
  void **base,
  UINT32 *unitSizeInBytes,
  UINT32 *nUnits,
  UINT32 *yStart,
  UINT32 *monitorEnabled,
  UINT32 *producerCumulativeUnits,
  UINT32 *consumerCumulativeUnits );

FUN_QUALIFIER DC_RETURN_CODE dc_container_debug_status_get
( DC_CONTAINER_DEBUG_HANDLE handle,
  UINT32 *production_state,
  UINT32 *consumption_state);

FUN_QUALIFIER DC_RETURN_CODE dc_dmbbuf_debug_info_get
( DC_CONTAINER_DEBUG_HANDLE handle,
  char **name,
  UINT32 *monitorEnabled,
  UINT32 *producerCumulativeUnits,
  UINT32 *producerCumulativeAuxUnits,
  UINT32 *consumerCumulativeUnits,
  UINT32 *consumerCumulativeAuxUnits,
  UINT32 *dmbsAllocated,
  UINT32 *dmbsFreed,
  DC_DMB *dmbHead,
  UINT32 *dmbSizeInBytes,
  DC_DMB *scratch_dmb1,
  UINT32 *scratch_offset1,
  UINT32 *scratch_alignedunit1,
  DC_DMB *scratch_dmb2,
  UINT32 *scratch_offset2,
  UINT32 *scratch_alignedunit2,
  UINT32 *scratch_units );




#undef FUN_QUALIFIER

#endif // dc_container_h




/*

---- Future work ----

Bug fix:

- If delete and never any consumers registered/unregistered, must free DMBs
  associated with container.

Container producer/consumer state and alerts:

- Add new API call xxx_{producer,consumer}_complete which indicates that the
  specified producer/consumer is done producing to / consuming from the
  container.

- Add explicit state for produce and consumer side of container
  - INIT, no producers/consumers have yet been registered
  - REGISTERED, one or more producers/consumers registered
  - ACTIVE, produce/consume active
    - entered when any producer/consumer 1st calls produce/consume
  - COMPLETE, produce/consume complete
    - entered when all producer/consumers have either call new complete API
      function to unregistered

- With above changes, we now can extend alerts to include produce/consume
  complete.

- We can probably also safely allow delete of an image container for which
  produce/consume state is INIT (no producers/consumers yet registerd) or
  COMPLETE.  In this case, we ought to provide additional alert to remaining
  registered producers/consumers that container has been deleted.


Container debug support:

- Extend the debug APIs to support a debug agent which resides on the firmware
  side (rather than on host like DBGMON).   Such a debug agent can achieve
  debug capability and deal with synchronization issues must more easily than
  poll mode DBGMON.

  - Also add a call out to a specified callback function to allow debugger
    to filter container name and decide whether to enable debug at create
    time.

  - Also add a callback which reports when containers are deleted.

DBGMON side:

- Not specific to container, but container debug experience would be better
  if DBGMON to FW and back round trip latency could be reduced, and if the
  speed of monMemRead and monMemWrite could be increased.

*/

